Skip to content

ci(publish): tag-driven npm publish with OIDC trusted publishing#24

Merged
joelshejar merged 1 commit into
mainfrom
ci/publish-workflow
May 11, 2026
Merged

ci(publish): tag-driven npm publish with OIDC trusted publishing#24
joelshejar merged 1 commit into
mainfrom
ci/publish-workflow

Conversation

@joelshejar
Copy link
Copy Markdown
Member

Summary

Step 10 of the release sequence. Replaces the existing release-trigger NPM_TOKEN workflow with the tag-driven OIDC trusted publishing flow we agreed on during the grilling pass.

What changes

`.github/workflows/publish.yml` (rewrite)

  • Triggers on `push` of `v*` tags + `workflow_dispatch` escape hatch.
  • Verifies the pushed tag matches the version field in all three publishable `package.json` files (fail-fast on drift).
  • Runs `pnpm -r build` and `pnpm exec vitest --run` before publishing.
  • Infers dist-tag from version suffix: `-alpha.` → `alpha`, `-beta.` → `beta`, `-rc./next.` → `next`, plain → `latest`.
  • Publishes `@tabmesh/core` → `transport-websocket` → `react` in dependency order.
  • Uses npm OIDC trusted publishing (`id-token: write` + `setup-node` with `registry-url`) and `--provenance`. No NPM_TOKEN secret needed.

`scripts/release.mjs` (new)

Helper that bumps all three `package.json` versions in lockstep, pins the `@tabmesh/core` peer-dep in the two dependents to the exact target version, commits, and creates the local tag.

Sample flow:
```bash
node scripts/release.mjs 0.1.0-alpha.0
git push origin main --tags

workflow runs, all three publish under @Alpha

```

Setup required before the first publish (one-time, npm-side, you do this)

  1. Create the `tabmesh` org on npmjs.com.
  2. For each of `@tabmesh/{core, react, transport-websocket}`:
    • Settings → Publishing access → Add trusted publisher
    • Repository: `CodeThicket/tabmesh`
    • Workflow file: `publish.yml`
    • Environment: leave empty

Test plan

  • Workflow YAML reviewed
  • `scripts/release.mjs` syntax checked locally
  • Biome clean
  • First publish (`v0.1.0-alpha.0`) — requires npm org + trusted publisher setup first

Replaces the existing publish workflow with a tag-driven flow that:

- Triggers on push of a `v*` tag (primary) or `workflow_dispatch`
  with a custom dist-tag (escape hatch).
- Verifies the pushed tag matches the version field in all three
  publishable package.json files (fail-fast if they drift).
- Runs `pnpm -r build` and `pnpm exec vitest --run` before publishing
  so a broken artifact never reaches the registry.
- Infers the npm dist-tag from the version suffix: -alpha. → alpha,
  -beta. → beta, -rc./next. → next, plain → latest.
- Publishes all three packages in dependency order (core, then
  transport-websocket, then react) so the registry resolves
  @tabmesh/core before its dependents are fetched.
- Uses npm OIDC trusted publishing (id-token: write + setup-node
  with registry-url) and the --provenance flag. No NPM_TOKEN secret
  needed; the GitHub Actions OIDC token is exchanged for a
  short-lived publish credential at the registry.

Also adds `scripts/release.mjs` — a small helper that bumps all
three package.json versions in lockstep, updates the
peer-dependency on @tabmesh/core in the two dependents to match
exactly (no caret — pre-1.0 versions are deliberately strict), and
creates the matching git tag locally. The user pushes the tag when
they're ready.

Sample release flow:

  node scripts/release.mjs 0.1.0-alpha.0
  git push origin main --tags
  # workflow runs, all three packages publish under @Alpha

Setup required before the first publish (one-time, on npm side):

  1. Create the `tabmesh` org on npmjs.com.
  2. For each of @tabmesh/{core,react,transport-websocket}:
       Settings → Publishing access → Add trusted publisher
       Repository: CodeThicket/tabmesh
       Workflow file: publish.yml
       Environment: (empty)
@joelshejar joelshejar merged commit 8b60fbf into main May 11, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant